package szf.im.client.boot;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import szf.im.client.data.MessageOuterClass;
import szf.im.client.handler.MyClientChannelHandler;
import szf.im.client.handler.ProtoBufHandler;
import szf.im.client.util.Cfg;
import szf.im.client.util.SpringUtil;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.Serializable;

/**
 * @author shizhanfu
 */
@Component
public class Client implements Serializable {
    public Channel channel;
    @Autowired
    private Cfg cfg;

    @PostConstruct
    public void start() throws IOException {
        System.out.println("client start begin at:" + cfg.getPort());
        Bootstrap bootstrap = new Bootstrap();
        EventLoopGroup parent = new NioEventLoopGroup();
        bootstrap.group(parent).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {

            @Override
            protected void initChannel(SocketChannel sc) throws Exception {
//                sc.pipeline().addLast(new StringDecoder());
//                sc.pipeline().addLast(new StringEncoder());
//                sc.pipeline().addLast(new MyClientChannelHandler());
                ChannelPipeline pipeline = sc.pipeline();
                //解码器，通过Google Protocol Buffers序列化框架动态的切割接收到的ByteBuf
                pipeline.addLast(new ProtobufVarint32FrameDecoder());
                //将接收到的二进制文件解码成具体的实例，这边接收到的是服务端的对象实列
                pipeline.addLast(new ProtobufDecoder(MessageOuterClass.Message.getDefaultInstance()));
                //Google Protocol Buffers编码器
                pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
                //Google Protocol Buffers编码器
                pipeline.addLast(new ProtobufEncoder());
                pipeline.addLast(new ProtoBufHandler());
            }
        });
        String routeUrl = getNettyServer();
        channel = bootstrap.connect(routeUrl.split(":")[0], Integer.parseInt(routeUrl.split(":")[1])).channel();
    }

    private String getNettyServer() throws IOException {
        OkHttpClient httpClient = new OkHttpClient();
        String path = "/route/server";
        Request request = new Request.Builder().url(cfg.getRouteUrl() + path).build();
        Response resp = httpClient.newCall(request).execute();
        if (resp.isSuccessful()) {
            return resp.body().string();
        }
        return "";
    }
}
